crypto = require 'crypto'
config = require './config'
md = require("node-markdown").Markdown
exutils = require('express/lib/utils')
util = require 'util'
sense = require 'SenseOrm'
Schema = sense.Schema
AbstractClass = sense.AbstractClass
db = new Schema 'redis', config.REDIS_CONFIG
db.log = (d)->
  console.log d
client = db.client

Type_Convert =
  #String: (v)->
  #  v
  Number: (v)->
    parseFloat(v)
  Date: (v)->
    new Date(v|0)
  Boolean: do ()->
    tmap =
      "true": true
      "false": false
    (v)->
      !!tmap[v]

AbstractClass.afterInitialize = do ()->
  ()->
    ctor = @constructor
    propers = ctor.schema.definitions[ctor.modelName].properties
    t = @

    Object.keys(propers).forEach (attr)->
      _attr = '_' + attr
      atype = propers[attr]?.type?.name
      if atype and (atype of Type_Convert)
        tc = Type_Convert[atype]
        if tc
          #console.log _attr, t[_attr], typeof(t[_attr])
          t[_attr] = tc t[_attr]
          #console.log _attr, t[_attr], typeof(t[_attr])

calcHash = () ->
  hash = crypto.createHash('sha256')
  for i in arguments
    hash.update i
  hash.digest 'hex'

User = db.define 'User',
  email: { type: String }
  nickname: { type: String, index: true}
  password: { type: String }
  gender: { type: Number , default: 0 } #0: Man, 1: Women, 2: Secret
  
  date_create: { type: Date, default: Date.now }
  date_login: { type: Date, default: Date.now }
  date_last: { type: Date, default: Date.now }
  nickname_low: { type: String }

  auth_qq_secret: String
  auth_qq_token: String
  auth_weibo_secret: String
  auth_weibo_token: String

User.setter.password = (password)->
  @_password = calcHash password, config.SALT
User.setter.nickname = (nickname)->
  @nickname_low = nickname.toLowerCase()
  @_nickname = nickname #there will be return.

User.validatesFormatOf 'email',
  with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  message: "无效的Email"
User.validatesUniquenessOf 'email',
  message: "该Email已经注册过了"
User.validatesUniquenessOf 'nickname',
  message: "昵称和已有用户昵称重复"
User.validatesLengthOf 'nickname',
  min: 3
  message:
    min: '昵称太短'
User.validateAsync 'nickname',
  (err, done)->
    if not /^[\w\u4e00-\u9fcb\u3400-\u4db5]{1,20}$/.test(@nickname)
      err('invaild')
    else
      User.all
        where:
          nickname_low: @nickname.toLowerCase()
        (us_err, us)->
          err('duplicate') if us.length > 0
          done()
  , message:
    duplicate: '昵称重复'
    invaild: '昵称无效'


Invite = db.define 'Invite',
  code: { type: String, index: true }
  done: { type: Number, default: 0 }
  user: { type: Number, default: 0 }
  
  date_create: { type: Date, default: Date.now }
  date_init: { type: Date, default: Date.now }

#User.hasOne, Invite
#Invite.belongsTo User, {as: 'user', foreignKey: 'ic' }

Attachment = db.define "Attachment",
  uri: { type: String }
  type: { type: String }

  date_create: { type: Date, default: Date.now }

User.hasMany Attachment, { as: 'attachs', foreignKey: 'id' }
Attachment.belongsTo User, { as: 'user', foreignKey: 'id' }

Post = db.define "Post",
  #title: { type: String }
  content: { type: db.Text }
  author_name: { type: String }
  ip: { type: String }
  address: { type: String }
  #tag_str: { type: String }

  date_create: { type: Date, default: Date.now }
  date_last: { type: Date, default: Date.now }
  show: { type: String, defualt: "show"} #show, spam, hidden
  img: { type: String }
  content_render: { type: db.Text }

Post.setter.content = (content)->
  @content_render = md(exutils.escape(content))
  @_content = content

User.hasMany Post, { as: 'posts', foreignkey: 'id' }
Post.belongsTo User, { as: 'user', foreignKey: 'id' }
Post.hasMany Attachment, { as: 'attachs', foreignkey: 'id' }
Attachment.belongsTo Post, { as: 'post', foreignKey: 'id' }

Tag = db.define "Tag",
  name: { type: String }
  url: { type: String }
  
  date_create: { type: Date, default: Date.now }
  date_last: { type: Date, default: Date.now }

Tag.setter.name = (name)->
  if not @url
    @url = name
  @_name = name

Tag.validatesUniquenessOf 'name',
  message: 'Tag名称重复'
Tag.validatesUniquenessOf 'url',
  message: 'Tag URL重复'

Tag_Post = db.define "Tag_Post"

#Tag_Post.belongsTo Tag, { as: "tag", foreignkey: 'id' }
#Tag_Post.belongsTo Post, { as: "post", foreignkey: 'id' }
Tag.hasMany Post, { as: 'posts', foreignkey: 'id' }
Post.hasMany Tag, { as: 'tags', foreignkey: 'id' }

  
module.exports =
  User: User
  Invite: Invite
  Attachment: Attachment
  Post: Post
  Tag: Tag
  Tag_Post: Tag_Post
  closeDB: ()-> db.disconnect()
  db: db
